package com.mlnx.web.unite.config;

import com.mlnx.common.entity.Response;
import com.mlnx.service.common.enums.ResponseEnum;
import com.mlnx.ui.service.UserService;
import com.mlnx.web.unite.exception.LoginException;
import com.mlnx.web.unite.utils.Md5;
import org.apache.commons.lang3.StringUtils;
import org.shan.security.core.authorize.AuthorizeConfigProvider;
import org.shan.security.resource.config.UserInfoProcess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * Created by amanda.shan on 2019/7/1.
 */
@Configuration
public class AuthConfig {

    @Autowired
    private UserService userService;

    @Bean
    public MlnxWebResponseExceptionTranslator translator() {
        return new MlnxWebResponseExceptionTranslator();
    }

    // 解析接口请求异常的处理类 下面只处理登入异常的情况
    static class MlnxWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {

        @Override
        public ResponseEntity translate(Exception e) throws Exception {

            if (e instanceof LoginException) {
                HttpHeaders headers = new HttpHeaders();
                ResponseEntity response =
                        new ResponseEntity(new Response(ResponseEnum.LOGIN_FAIL.getCode(),
                                e.getMessage()),
                                headers, HttpStatus.FORBIDDEN);

                return response;

            } else {
                return super.translate(e);
            }
        }

    }



    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

                com.mlnx.ui.entity.User userAccount = userService.getById(Integer.parseInt(username));

                if (userAccount == null) {

                    throw new UsernameNotFoundException(username + "用户不存在");
                } else {

                    String[] strings = new String[0];

                    return new User(username, userAccount.getPassword(),
                            AuthorityUtils.createAuthorityList(strings));
                }
            }
        };
    }

    /**
     * 设置url拦截权限
     *
     * @return
     */
    @Bean
    public AuthorizeConfigProvider authorizeConfigProvider() {
        return new AuthorizeConfigProvider() {

            @Override
            public boolean config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
                registry.anyRequest().permitAll();
//                registry.antMatchers("/device/**").permitAll();
//                registry.antMatchers("/area/**", "/device-channel/**", "/device/**", "/device-quality/**",
//                        "/hospital/**","/quality-type/**", "/quality-data/**", "/data/**", "/test-item/**").authenticated();
                return true;
            }
        };
    }

    @Bean
    public UserInfoProcess userInfoProcess(){
        return new UserInfoProcess() {
            @Override
            public void process(Authentication authentication, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {

                String username = null;
                Object principal = authentication.getPrincipal();
                if (principal instanceof User){
                    User user = (User) principal;
                    username = user.getUsername();
                }else{
                    username = principal.toString();
                }

                if (!StringUtils.isEmpty(username)) {
                    httpServletRequest.setAttribute("username", username);
                }
            }
        };
    }

    @Bean
    @Primary
    public PasswordEncoder passwordEncoders(){
        return new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return Md5.string2MD5(charSequence.toString());
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {

                return  (encode(charSequence)).equals(s);
            }
        };
    }

}
